﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text.RegularExpressions;
using System.Configuration;
using System.Text;
using System.Data;

namespace Heyu.Utility
{
    /// <summary>
    /// 字符串处理类
    /// </summary>
    public class StringUtility
    {
        #region  Html

        /// <summary>
        /// HTML解码
        /// </summary>
        /// <remarks>HTML解码</remarks>
        /// <param name="s">字符串</param>
        /// <returns>string</returns>
        public static string HtmlDecode(string s)
        {
            string str;
            try
            {
                str = HttpContext.Current.Server.HtmlDecode(s).Replace("[&quot;]", "\"").Replace("[&#39;]", "'");
            }
            catch
            {
                str = "";
            }
            return str;
        }

        /// <summary>
        /// 去掉所有HTML代码
        /// </summary>
        /// <param name="s">传入的字符串</param>
        /// <returns>去掉所有HTML代码后的字符串</returns>
        public static string StripHtml(string s)
        {
            string strOutput = "";
            if (s != null && s != "")
            {
                Regex regex = new Regex("<.+?>", RegexOptions.IgnoreCase);
                strOutput = regex.Replace(s, "");
            }
            return strOutput.Replace("&nbsp;", "").Trim();
        }

        /// <summary>  
        /// 为关键词加上超链接  
        /// </summary>  
        /// e.g.:   
        /// string result=GetInnertLink("<a href="http//www.baidu.com" mce_href="http/www.baidu.com">Ningxi</a>Xi过得<span>XI<span>好<a href="http://www.ningxi.com" mce_href="http://www.ningxi.com">快乐</a>！","xi","ningxi","http://www.ningxi.com","_blank",0)  
        /// <param name="htmlcode">要把关键词加上超链接的html源文本</param>  
        /// <param name="keyword">将要加上超链接的关键词</param>  
        /// <param name="title">将要加上的超链接的描文本</param>  
        /// <param name="url">将要加上的超链接的url地址</param>  
        /// <param name="target">将要加上的超链接的打开方式</param>  
        /// <param name="num">为html文本内的前num个关键词加上超链接,0代表全加上超链接</param>  
        /// <returns>返回为关键词加上超链接后的html文本</returns>  
        private static string GetInnertLink(string htmlcode, string keyword, string title, string url, string target, int num)
        {
            string htmlcodeResult = htmlcode;  //用于保存最新的html文本
            string htmlcodeLower = htmlcodeResult.ToLower();  //用于保存最新的Hmtl文本的小写，方便不分大小写找出关键词
            string keywordResult = "";  //用于保存关键词的原来面貌，可能是大写，或者有大也有小
            int keyIndex = 0;           //关键词所在位置
            int currentIndex = 0;       //每次搜索关键词的开始位置
            int currentNum = 0;         //保存当前加上了多少个有效超链接
            int LBracketIndex = 0;      //左尖括号<位置
            int RBracketIndex = 0;      //右尖括号>位置
            if (num == 0)
            {
                num = htmlcode.Length;
            }
            while (currentIndex <= htmlcodeLower.Length && currentNum < num)
            {
                if (htmlcodeLower.IndexOf(keyword.ToLower(), currentIndex) > -1)
                {
                    keyIndex = htmlcodeLower.IndexOf(keyword.ToLower(), currentIndex);
                    LBracketIndex = keyIndex;
                    do
                    {
                        LBracketIndex = htmlcodeLower.LastIndexOf("<", LBracketIndex - 1, LBracketIndex - currentIndex);
                    }
                    while (LBracketIndex != -1 && htmlcodeLower.Substring(LBracketIndex + 1, 1) == "/");
                    RBracketIndex = htmlcodeLower.LastIndexOf(">", keyIndex - 1, keyIndex - currentIndex);
                    if (LBracketIndex <= RBracketIndex)
                    {
                        //不在标签的属性内，可以有在标签开始与结束标志内，或在开始与结束标志外  
                        LBracketIndex = htmlcodeLower.LastIndexOf("<", keyIndex - 1, keyIndex - currentIndex);
                        if (LBracketIndex != -1 && htmlcodeLower.Substring(LBracketIndex + 1, 1) != "/")
                        {
                            //在开始与结束标志内  
                            //关键词在开始标签与结束标签内，要再判定是不是a标签或pre标签  
                            if (htmlcodeLower.Substring(LBracketIndex + 1, 1) == "a" || htmlcodeLower.Substring(LBracketIndex + 3, 3) == "pre")
                            {
                                //关键词在开始与结束a标签或pre标签内，不可加超链接，循环再来  
                                currentIndex = keyIndex + keyword.Length;
                            }
                            else
                            {
                                //可以加超链接  
                                keywordResult = htmlcodeResult.Substring(keyIndex, keyword.Length);
                                htmlcodeResult = htmlcodeResult.Remove(keyIndex, keyword.Length);
                                htmlcodeResult = htmlcodeResult.Insert(keyIndex, "<a href=" + url + " mce_href=" + url + " title=" + title + " target=" + target + ">" + keywordResult + "</a>");
                                htmlcodeLower = htmlcodeResult.ToLower();
                                currentIndex = htmlcodeResult.IndexOf("</a>", keyIndex) + 4;
                                currentNum += 1;
                            }
                        }
                        else
                        {
                            //在结束标志外,可以加超链接  
                            keywordResult = htmlcodeResult.Substring(keyIndex, keyword.Length);
                            htmlcodeResult = htmlcodeResult.Remove(keyIndex, keyword.Length);
                            htmlcodeResult = htmlcodeResult.Insert(keyIndex, "<a href=" + url + " mce_href=" + url + " title=" + title + " target=" + target + ">" + keywordResult + "</a>");
                            htmlcodeLower = htmlcodeResult.ToLower();
                            currentIndex = htmlcodeResult.IndexOf("</a>", keyIndex) + 4;
                            currentNum += 1;
                        }
                    }
                    else
                    {
                        //关键词是标签内的属性值，不可加超链接，循环再来  
                        currentIndex = keyIndex + keyword.Length;
                    }
                }
                else
                {
                    currentIndex = htmlcodeLower.Length + 1;
                }
            }
            return htmlcodeResult;
        }

        /// <summary>
        /// 从编辑器中获取图片
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string GetImgString(string str)
        {
            string res = "";
            string tem = "";
            int startIndex = 0;
            int endIndex = 0;
            for (int i = 0; i < str.Length - 4; i++)
            {
                tem = str.Substring(i, 4).ToLower();
                if (tem == "<img")
                {
                    startIndex = i;
                    str = str.Substring(startIndex);
                    endIndex = str.IndexOf('>');
                    res = str.Substring(0, endIndex + 1);
                    str = str.Substring(endIndex);
                    res += GetImgString(str); //递归调用                
                    break;
                }
            }
            return res;
        }
        #endregion

        #region 字符串截取
        ///   <summary> 
        ///   将指定字符串按指定长度进行剪切， 
        ///   </summary> 
        ///   <param   name= "oldStr "> 需要截断的字符串 </param> 
        ///   <param   name= "maxLength "> 字符串的最大长度 </param> 
        ///   <param   name= "endWith "> 超过长度的后缀 </param> 
        ///   <returns> 如果超过长度，返回截断后的新字符串加上后缀，否则，返回原字符串 </returns> 
        public static string StringTruncat(string oldStr, int maxLength)
        {
            if (string.IsNullOrEmpty(oldStr))
            {
                //throw new NullReferenceException("原字符串不能为空 "); 
                return oldStr;
            }
            if (maxLength < 1)
            {
                throw new Exception("返回的字符串长度必须大于[0] ");
            }
            if (oldStr.Length > maxLength)
            {
                string strTmp = oldStr.Substring(0, maxLength);
                return strTmp + "...";
            }
            else
            {
                return oldStr;
            }
        }
        #endregion

        #region 日期
        /// <summary>
        /// 返回日期格式（2012-12-12）
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public static string DateFormat(object o, string separator = "-")
        {
            string res = "";
            try
            {
                if (o.ToString() != "")
                {
                    DateTime date = Convert.ToDateTime(o);
                    res = date.ToString("yyyy" + separator + "MM" + separator + "dd");
                }
            }
            catch (Exception e)
            {
                res = e.Message;
            }
            return res;
        }

        public static int DateToInt(object o)
        {
            int res = 0;
            try
            {
                if (o.ToString() != "")
                {
                    DateTime date = Convert.ToDateTime(o);
                    res = Convert.ToInt32(date.ToString("yyyyMMdd"));
                }
            }
            catch
            {
            }
            return res;
        }
        #endregion

        public static string PhoneHidden(string phone)
        {
            return Regex.Replace(phone, @"(?im)(\d{3})(\d{4})(\d{4})", "$1****$3");
        }

        public static string EmailHidden(string email)
        {
            string[] arr_email = email.Split('@');
            string account = arr_email[0].Substring(0, 2) + "******" + arr_email[0].Substring(arr_email[0].Length - 2, 2);
            string mail = arr_email[1];

            return account + "@" + mail;
        }

        /// <summary>
        /// 判断datarow中 是否包含某列
        /// </summary>
        /// <param name="dr"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static bool ColumnContains(DataRow dr, string name)
        {
            return dr.Table.Columns.Contains(name);
        }

        /// <summary>    
        /// 获得当前页面客户端的IP    
        /// </summary>    
        /// <returns>当前页面客户端的IP</returns>    
        public static string GetIP()
        {
            string result = String.Empty;
            result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            if (string.IsNullOrEmpty(result))
            {
                result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            }
            if (string.IsNullOrEmpty(result))
            {
                result = HttpContext.Current.Request.UserHostAddress;
            }
            if (string.IsNullOrEmpty(result))
            {
                return "127.0.0.1";
            }
            return result;
        }
        

        #region 将生日转换为年龄


        public static int getAge(object birthday)
        {
            if (birthday != null & birthday.ToString() != "")
            {
                DateTime date = Convert.ToDateTime(birthday);
                DateTime dateNow = DateTime.Now;
                int yearNow = dateNow.Year;
                int yearBirth = date.Year;
                return yearNow - yearBirth;
            }
            else
            {
                return 0;
            }

        }
        /// <summary>
        /// 根据出生日期获取年龄
        /// </summary>
        /// <param name="birthday"></param>
        /// <returns></returns>
        public static int getAgeByBirthday(DateTime birthday)
        {
            int age = 0;
            if (birthday != null & birthday.ToString() != "")
            {
                DateTime date = Convert.ToDateTime(birthday);
                DateTime dateNow = DateTime.Now;

                age = DateTime.Now.Year - birthday.Year;//根据年份初步计算年龄

                if (birthday.Month > DateTime.Now.Month)
                {
                    //如果生日的月份大于今天，那么实际年龄需要-1
                    age -= 1;
                }
                else if (DateTime.Now.Month == birthday.Month)
                {
                    //如果月份相等，那么计算天数
                    if (birthday.Day >= DateTime.Now.Day)
                    {
                        age -= 1;
                    }
                }
            }

            return age;
        }
        /// <summary>
        /// 根据身份证号获取生日
        /// </summary>
        /// <param name="sfzh"></param>
        /// <returns></returns>
        public static string getBirthdayBySfzh(string sfzh)
        {
            string res;

            string year = "", month = "", day = "";
            switch (sfzh.Length)
            {
                case 15:
                    year = "19" + sfzh.Substring(6, 2).ToString();
                    month = sfzh.Substring(8, 2);
                    day = sfzh.Substring(10, 2);
                    break;
                case 18:
                    year = sfzh.Substring(6, 4).ToString();
                    month = sfzh.Substring(10, 2);
                    day = sfzh.Substring(12, 2);
                    break;
            }

            try
            {
                res = Convert.ToDateTime(year + "-" + month + "-" + day).ToString("yyyy-MM-dd");
            }
            catch (Exception ex)
            {
                res = "身份证号不正确，获取出生日期失败！" + ex.Message;
            }

            return res;
        }
        /// <summary>
        /// 根据出生日期，获取最大有效期止
        /// </summary>
        /// <param name="birthday">出生日期</param>
        /// <param name="year">年份（出生日期+多少年）</param>
        /// <param name="maxAge">最大年龄</param>
        /// <param name="startDate">开始日期</param>
        /// <returns></returns>
        public static DateTime getYxqzByBirthday(DateTime birthday, int year, int maxAge, DateTime startDate)
        {
            DateTime norDate = startDate.AddYears(year);//默认日期
            DateTime maxDate = birthday.AddYears(maxAge);//最大日期
            if (norDate > maxDate)
            {
                //如果默认日期，大于最大日期，那么表示超过限制日期了，去较小的有效期
                return maxDate;
            }
            else
            {
                return norDate;
            }
        }

        /// <summary>
        /// 根据出生日期，获取最大有效期止
        /// </summary>
        /// <param name="birthday">出生日期</param>
        /// <param name="year">年份（出生日期+多少年）</param>
        /// <param name="maxAge">最大年龄</param>
        /// <returns></returns>
        public static DateTime getYxqzByBirthday(DateTime birthday, int year, int maxAge)
        {
            return getYxqzByBirthday(birthday, year, maxAge, DateTime.Now);
        }
        #endregion

        public static int DecimalToInt(decimal value)
        {
            int res = 0;
            try
            {
                res = Convert.ToInt32(Math.Ceiling(value));
            }
            catch
            {
            }
            return res;
        }


        /// <summary>
        /// 判断字符串是否存在数组中
        /// </summary>
        /// <param name="arr"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool StringInArray(string[] arr, string value, bool allowSpace = true)
        {
            bool flag = false;
            foreach (string str in arr)
            {
                if (allowSpace)
                {
                    if (str.Trim().Equals(value.Trim()))
                    {
                        flag = true;
                        break;
                    }
                }
                else
                {
                    if (str.Equals(value))
                    {
                        flag = true;
                        break;
                    }
                }
            }
            return flag;
        }

        /// <summary>
        /// 数组转化成字符串
        /// </summary>
        /// <param name="arr"></param>
        /// <returns></returns>
        public static string ArrToString(string[] arr, string separator = "、")
        {
            string res = "";
            for (int i = 0; i < arr.Length; i++)
            {
                if (i == 0)
                {
                    res += arr[i];
                }
                else
                {
                    res += separator + arr[i];
                }
            }
            return res;
        }
        /// <summary>
        /// 数组转化成字符串(用引号包含)
        /// </summary>
        /// <param name="arr"></param>
        /// <param name="separator"></param>
        /// <returns></returns>
        public static string ArrToString2(string[] arr, string separator = "、")
        {
            string res = "";
            for (int i = 0; i < arr.Length; i++)
            {
                string value = "\"" + arr[i] + "\"";
                if (i == 0)
                {
                    res += value;
                }
                else
                {
                    res += separator + value;
                }
            }
            return res;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="column"></param>
        /// <returns></returns>
        public static string DataTableToString(DataTable dt, int column = 0, string separator = "、")
        {
            string res = "";
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (i == 0)
                {
                    res += dt.Rows[i][column];
                }
                else
                {
                    res += separator + dt.Rows[i][column];
                }
            }
            return res;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="column"></param>
        /// <returns></returns>
        public static List<string> DataTableToList(DataTable dt, int column = 0)
        {
            List<string> list = new List<string>();
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                list.Add(dt.Rows[i][column].ToString());
            }
            return list;
        }
        public static string[] DataTableToArray(DataTable dt, int column = 0)
        {
            return DataTableToList(dt, column).ToArray();
        }

        #region 随机数
        /// <summary>
        /// 生成随机数
        /// </summary>
        /// <param name="num">位数</param>
        /// <returns></returns>
        public static string getRandom(int num)
        {
            string a = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < num; i++)
            {
                sb.Append(a[new Random(Guid.NewGuid().GetHashCode()).Next(0, a.Length - 1)]);
            }
            return sb.ToString();
        }
        public static string RandNum(int length)
        {
            string res = ""; ;
            Random random = new Random();
            for (int i = 0; i < length; i++)
            {
                res += random.Next(9);
            }
            return res;
        }
        public static string RandString(int length)
        {
            char[] constant = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };

            System.Text.StringBuilder newRandom = new System.Text.StringBuilder(62);
            Random random = new Random();
            for (int i = 0; i < length; i++)
            {
                newRandom.Append(constant[random.Next(62)]);
            }
            return newRandom.ToString();
        }
        #endregion

        #region 转换星期几为中文

        public static string GetMonthOfEn(int month)
        {
            string mon = "";
            string[] arr_mon = { "Jua", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

            for (int i = 1; i <= 12; i++)
            {
                if (i == month)
                {
                    mon = arr_mon[i - 1];
                }
            }
            return mon;
        }

        /// <summary>
        /// 转换星期几为中文
        /// </summary>
        /// <param name="week">星期(英文)</param>
        /// <returns>星期(中文)</returns>
        public static string GetWeek(string week)
        {
            string xingqi = "";
            switch (week)
            {
                case "Sunday":
                    xingqi = "星期天";
                    break;
                case "Monday":
                    xingqi = "星期一";
                    break;
                case "Tuesday":
                    xingqi = "星期二";
                    break;
                case "Wednesday":
                    xingqi = "星期三";
                    break;
                case "Thursday":
                    xingqi = "星期四";
                    break;
                case "Friday":
                    xingqi = "星期五";
                    break;
                case "Saturday":
                    xingqi = "星期六";
                    break;
                default:
                    xingqi = "格式不正确";
                    break;
            }
            return xingqi;
        }
        #endregion


        public static string IntToDate(string value)
        {
            try
            {
                return value.Substring(0, 4) + "-" + value.Substring(4, 2) + "-" + value.Substring(6, 2);
            }
            catch
            {
                return "";
            }
        }
        public static DateTime IntToDateTime(string value)
        {
            string date = IntToDate(value);
            if (date != "")
            {
                return Convert.ToDateTime(date);
            }
            else
            {
                return Convert.ToDateTime("1900-1-1");
            }
        }
        public static int DateToInt(string date)
        {
            int res = 0;
            if (date != "")
            {
                try
                {
                    res = int.Parse(Convert.ToDateTime(date).ToString("yyyyMMdd"));
                }
                catch
                {
                }
            }
            return res;
        }


    }
}